#include "Common.h"

ItemInterface::ItemInterface(Player* pPlayer)
{
	m_owner = pPlayer;
}

void ItemInterface::AddItemToSlot(Item* item, ui8 slot)
{
	if(!m_owner)
	{
		Log->Error("ItemInterface", "!m_owner");
		return;
	}
	if(m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2)) && slot < 19)
	{
		Log->Error("ItemInterface", "m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2))");
		return;
	}
	if(!item)
	{
		Log->Error("ItemInterface", "!item");
		return;
	}
	if(!item->GetInfo())
		Log->Error("ItemInterface", "!item->getInfo()");
	m_owner->SetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), item->GetGUID());
	stringstream strm;
	strm << "Replace into playeritems VALUES("
		<< item->GetUI32Value(ITEM_FIELD_OWNER) << " , " << (ui32)item->GetGUID() << " , "
		<< item->GetUI32Value(OBJECT_FIELD_ENTRY) << " , " << (ui32)slot << ")";
	CharacterDatabase.Query(strm.str().c_str());
	RealmPacket update(0, 0);
	item->BuildCreation(m_owner, &update);
	m_owner->PushCreationData(&update);
	if(slot < 19)
	{
		ui32 base = PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2);
		if(base > PLAYER_VISIBLE_ITEM_19_ENTRYID)
			return;
		m_owner->SetUI32Value(base, item->GetEntry());
		m_owner->SetUI32Value(base + 1, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1));
		/*m_owner->SetUI32Value(base + 2, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 3));
		m_owner->SetUI32Value(base + 3, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 6));
		m_owner->SetUI32Value(base + 4, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 9));
		m_owner->SetUI32Value(base + 5, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 12));
		m_owner->SetUI32Value(base + 6, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 15));
		m_owner->SetUI32Value(base + 7, item->GetUI32Value(ITEM_FIELD_ENCHANTMENT_1_1 + 18));
		m_owner->SetUI32Value(base + 13, item->GetUI32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID));*/
	}
}

void Session::HandleItemQuerySingle(RealmPacket& rdata)
{
	ui32 id;
	rdata >> id;
	ItemInfo* itemProto = miscmgr->GetItemInfo(id);
	if(!itemProto)
		return;

	string* locale = sDatabaseLocal.GetItemNameLocale(id, m_account->country);
	RealmPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE);
	data << itemProto->ItemId;
	data << itemProto->Class;
	data << itemProto->SubClass;
	data << itemProto->unknown_bc;
	if(!locale)
		data << itemProto->Name1;
	else
		data << WoWString(locale->c_str());
	data << ui8(0) << ui8(0) << ui8(0);
	data << itemProto->DisplayInfoID;
	data << itemProto->Quality;
	data << itemProto->Flags;
	data << itemProto->BuyPrice;
	data << itemProto->SellPrice;
	data << ui32(0);
	data << itemProto->InventoryType;
	data << itemProto->AllowableClass;
	data << itemProto->AllowableRace;
	data << itemProto->ItemLevel;
	data << itemProto->RequiredLevel;
	data << itemProto->RequiredSkill;
	data << itemProto->RequiredSkillRank;
	data << itemProto->RequiredSpell;
	data << itemProto->RequiredPlayerRank1;
	data << itemProto->RequiredPlayerRank2;
	data << itemProto->RequiredFaction;
	data << itemProto->RequiredFactionStanding;
	data << itemProto->Unique;
	data << itemProto->MaxCount;
	data << itemProto->ContainerSlots;
	data << itemProto->itemstatscount;
	for(ui32 i = 0; i < itemProto->itemstatscount; i++)
	{
		data << itemProto->Stats[i].Type;
		data << itemProto->Stats[i].Value;
	}
	data << itemProto->ScalingStatsEntry;
	data << itemProto->ScalingStatsFlag;
	for(ui32 i = 0; i < 2; i++)
	{
		data << itemProto->Damage[i].Min;
		data << itemProto->Damage[i].Max;
		data << itemProto->Damage[i].Type;
	}
	data << itemProto->Armor;
	data << itemProto->HolyRes;
	data << itemProto->FireRes;
	data << itemProto->NatureRes;
	data << itemProto->FrostRes;
	data << itemProto->ShadowRes;
	data << itemProto->ArcaneRes;
	data << itemProto->Delay;
	data << itemProto->AmmoType;
	data << itemProto->Range;
	for(ui32 i = 0; i < 5; i++) 
	{
		data << itemProto->Spells[i].Id;
		data << itemProto->Spells[i].Trigger;
		data << itemProto->Spells[i].Charges;
		data << itemProto->Spells[i].Cooldown;
		data << itemProto->Spells[i].Category;
		data << itemProto->Spells[i].CategoryCooldown;
	}
	data << itemProto->Bonding;
	data << itemProto->Description;

	data << itemProto->PageId;
	data << itemProto->PageLanguage;
	data << itemProto->PageMaterial;
	data << itemProto->QuestId;
	data << itemProto->LockId;
	data << itemProto->LockMaterial;
	data << itemProto->Field108;
	data << itemProto->RandomPropId;
	data << itemProto->RandomSuffixId;
	data << itemProto->Block;
	data << itemProto->ItemSet;
	data << itemProto->MaxDurability;
	data << itemProto->ZoneNameID;
	data << itemProto->MapID;
	data << itemProto->BagFamily;
	data << itemProto->TotemCategory;
	data << itemProto->Sockets[0].SocketColor;
	data << itemProto->Sockets[0].Unk;
	data << itemProto->Sockets[1].SocketColor;
	data << itemProto->Sockets[1].Unk;
	data << itemProto->Sockets[2].SocketColor;
	data << itemProto->Sockets[2].Unk;
	data << itemProto->SocketBonus;
	data << itemProto->GemProperties;
	data << itemProto->DisenchantReqSkill;
	data << itemProto->ArmorDamageModifier;
	data << itemProto->ExistingDuration;
	data << itemProto->ItemLimitCategory;
	SendPacket(&data);
}

Item* ItemInterface::GetItemAt(ui8 slot)
{
	if(slot > 117)
		return 0;
	if(!m_owner)
		return 0;
	ui64 guid = m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2));
	return miscmgr->GetItem(guid);
}

ui32 ItemInterface::GetItemCount(ui32 itemid)
{
	ui32 count_ = 0;
	for(register ui32 i = 0; i < 117; ++i)
	{
		Item* im = GetItemAt(i);
		if(im && im->GetEntry() == itemid)
			count_ += im->GetUI32Value(ITEM_FIELD_STACK_COUNT);
	}
	return count_;
}

void ItemInterface::SendChangeFailed(ui8 src, ui8 dest, ui8 error)
{
	if(!m_owner)
		return;
	RealmPacket data(SMSG_INVENTORY_CHANGE_FAILURE);
	data << error;
	if(error == 1)
	{
		Item* im = miscmgr->GetItem(m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (src * 2)));
		if(im)
			data << im->GetInfo()->RequiredLevel;
	}
	if(m_owner)
	{
		data << m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (src * 2));
		data << m_owner->GetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (dest * 2));
	}
	else
		data << ui64(0) << ui64(0);
	data << ui8(0);
	if(m_owner)
		m_owner->GetSession()->SendPacket(&data);
}

void ItemInterface::SwapItems(ui8 slot1, ui8 slot2, Item* i1, Item* i2)
{
	if(!m_owner)
		return;
	m_owner->SetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot1 * 2), 0);
	m_owner->SetUI64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot2 * 2), 0);
	AddItemToSlot(i2, slot1);
	AddItemToSlot(i1, slot2);
}




void Session::HandleItemSwap(RealmPacket& rdata)
{
	ui8 src, dest;
	rdata >> src >> dest;
	if(src == dest)
	{
		m_player->GetItemInterface()->SendChangeFailed(src, dest, 21);
		return;
	}
	Item* srci = m_player->GetItemInterface()->GetItemAt(src);
	Item* desti = m_player->GetItemInterface()->GetItemAt(dest);

	if(!srci)
	{
		m_player->GetItemInterface()->SendChangeFailed(src, dest, 54);
		return;
	}

	m_player->GetItemInterface()->SwapItems(src, dest, srci, desti);
}

void Session::HandleUseItem(RealmPacket& data)
{
	i8 container, slot;
	ui8 unk, castnumber;
	ui64 itemguid;
	ui32 spellid, glyph;
	data >> container >> slot >> castnumber >> spellid >> itemguid >> glyph >> unk;
	Spell* sp = new Spell(m_player, dbcSpells.LookupEntry(spellid), castnumber);
	sp->FillTargets(m_player->GetGUID(), &data);
	sp->Start();
}